﻿using Grabacr07.KanColleViewer.Composition;
using Grabacr07.KanColleViewer.Models;
using Grabacr07.KanColleViewer.Views.Controls;
using Grabacr07.KanColleWrapper.Models;
using Grabacr07.KanColleWrapper.Models.Raw;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Net;
using System.Reactive.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;

namespace SubTitles
{
    [Export(typeof(IPlugin))]
    [ExportMetadata("Guid", "45c42079-897b-43c0-87bf-5e6e0284a3b3")]
    [ExportMetadata("Title", "SubTitles")]
    [ExportMetadata("Description", "汉化字幕")]
    [ExportMetadata("Version", "0.1")]
    [ExportMetadata("Author", "Mystic Monkey")]
    public class Program : IPlugin
    {
        private static readonly FileInfo dataFile = new FileInfo(Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
            "grabacr.net",
            "KanColleViewer",
            "Serif.xml"));
        private Model.Data Data;
        private Dictionary<string, int> ShipId = new Dictionary<string, int>();

        public void Initialize()
        {
            // 处理数据
            if (!dataFile.Exists || dataFile.LastWriteTime < DateTime.Now.AddDays(-7))
                GetData();
            else
            {
                using (FileStream fs = new FileStream(dataFile.FullName, FileMode.Open))
                {
                    XmlSerializer serial = new XmlSerializer(typeof(Model.Data));
                    Data = serial.Deserialize(fs) as Model.Data;
                }
            }

            Grabacr07.KanColleWrapper.KanColleClient.Current.Proxy.api_start2.FirstAsync().Subscribe(session =>
            {
                SvData<kcsapi_start2> svd;
                if (!SvData.TryParse(session, out svd))
                    return;

                foreach (Api_Mst_Shipgraph i in svd.Data.api_mst_shipgraph)
                    ShipId.Add(i.api_filename, i.api_id);
            });
            Nekoxy.HttpProxy.AfterSessionComplete += HttpProxy_AfterSessionComplete;
        }

        private void HttpProxy_AfterSessionComplete(Nekoxy.Session session)
        {
            Match match = Regex.Match(session.Request.RequestLine.URI, "/kcs/sound/kc(.+?)/(.+?).mp3");
            if (match.Success)
            {
                try
                {
                    session.Response.Headers.Headers["Pragma"] = "no-cache";
                    session.Response.Headers.Headers["Cache-Control"] = "no-cache";

                    int ship = ShipId[match.Groups[1].Value];
                    Model.Voice voice = Data.VoiceList
                        .Where(i => i.ShipIndex == ship)
                        .FirstOrDefault(i => i.ShipIndex == ship & match.Groups[2].Value == getVoiceId(ship, i.VoiceIndex)
                        .ToString());

                    if (!string.IsNullOrEmpty(voice.Translation))
                    {
                        //INotification notify = Notification.Create(
                        //    "Serif",
                        //    Grabacr07.KanColleWrapper.KanColleClient.Current.Master.Ships[ship].Name,
                        //    voice.Translation);
                        //NotifyService.Current.Notify(notify);

                        StatusService.Current.Notify(
                            Grabacr07.KanColleWrapper.KanColleClient.Current.Master.Ships[ship].Name + "：" +
                            voice.Translation);
                    }
                }
                catch { }
            }
        }

        /// <summary>
        /// 从服务器获取数据
        /// </summary>
        private async void GetData()
        {
            try
            {
                HttpWebRequest HttpWReq = (HttpWebRequest)WebRequest.Create("http://smdhz.github.io/Files/Serif.xml");
                HttpWebResponse HttpWResp = (HttpWebResponse)await HttpWReq.GetResponseAsync();

                XmlSerializer serial = new XmlSerializer(typeof(Model.Data));
                Data = serial.Deserialize(HttpWResp.GetResponseStream()) as Model.Data;
                using (FileStream fs = new FileStream(dataFile.FullName, FileMode.Create))
                    serial.Serialize(fs, Data);
                HttpWResp.Close();
            }
            catch (WebException) { }
        }

        private int getVoiceId(int ship, int voice) => (ship + 7) * 17 * (Data.VoiceKeys[voice] - Data.VoiceKeys[voice - 1]) % 99173 + 100000;
    }
}
